;*********************************************************** ; シリアル通信動作チェックプログラム ; パソコンから文字列(文字の最後は「CR」)を送る。 ; PIC側では、文字列を受信してバッファに格納する。 ; もしデータが、「CR」だったらそれまでのデータを送信出力する。 ; また、バッファが一杯になったときも送信する。 ; 文字列の最後には「終了」のメッセージを付加して送信を終了する。 ; ; 非同期式通信モード ; ボーレート 9600bps ; 8ビット・ノンパリティ ; 割り込みは使用しない ;*********************************************************** LIST P=PIC16F877 ; プロセッサの種別指定 INCLUDE "P16F877.INC" ; インクルードファイルの指定 ;*********************************************************** ; 変数定義とレジスタ割付 ;*********************************************************** TEMP EQU 20H ; ワークエリア POINT EQU 21H ; テーブルポインタ ORG 0 ; プログラムの開始番地の指定 ;*********************************************************** ; 送受信モードの初期化 ; (注)バンクの位置に注意 ;*********************************************************** BSF STATUS,RP0 ; Bank 1 へ切替 MOVLW B'10111111' ; RC7/RX(入力),RC6/TX(出力) MOVWF TRISC ; PORTC の設定 MOVLW B'00100100' ; 8BIT,送信許可,非同期,高速 MOVWF TXSTA ; TXSTA レジスタの設定 MOVLW 81H ; ボーレート 9600bps (20MHz:高速設定時) MOVWF SPBRG ; SPBRG レジスタの設定 BCF STATUS,RP0 ; Bank 0 へ戻す MOVLW B'10010000' ; シリアル,8BIT,継続受信許可 MOVWF RCSTA ; RCSTA レジスタの設定 ;*********************************************************** ; メインプログラム ; ; データを受信し、バッファに格納する。 ; もしデータが、「CR」だったらそれまでのデータを送信出力する。 ; また、バッファが一杯になったときも送信する。 ;*********************************************************** MAIN ; メインルーチン ; ****** データの受信ルーチン ****** BSF STATUS,IRP ; 間接アドレス設定 MOVLW 0A0H ; バッファの先頭アドレスをセットする MOVWF FSR ; 間接アドレスポインタの初期化 LPRCV BTFSS PIR1,RCIF ; USART 受信割り込みフラグビットのチェック GOTO LPRCV ; PIR1 レジスタの RCIF が「0」だったら ; LPRCV ラベル間をループする ; ****** エラーチェック ****** BTFSC RCSTA,FERR ; フレーミングエラーのチェック(1:エラー,0:正常) GOTO FRAME ; フレーミングエラー時 FRAME のラベルへ ; ジャンプする BTFSC RCSTA,OERR ; オーバーランエラーのチェック(1:エラー,0:正常) GOTO OVER ; オーバーランエラー時 OVER のラベルへジャンプする ; ****** 受信データの格納 ****** MOVF RCREG,W ; RCREGレジスタから受信データを読み込む MOVWF INDF ; バッファに格納 SUBLW 0DH ; 受信データから「CR」コードを引く BTFSC STATUS,Z ; 演算結果がゼロかチェック(受信データは「CR」?) GOTO SEND ; 受信データが「CR」のとき SENDのラベルへジャンプする CHKBF ; ****** バッファが一杯かどうかチェック ****** INCF FSR,F ; ポインタ +1 BTFSS STATUS,Z ; STATUSレジスタのZフラグビットが1だったら次をスキップ GOTO LPRCV ; バッファに余裕あり LPRCVのラベルへ戻り受信を続ける GOTO SEND ; バッファが一杯   SEND のラベルへジャンプする ; ****** エラー時の処理 ****** FRAME ; <フレーミングエラー時の処理> MOVF RCREG,W ; ダミーの入力とFERRフラグをリセット(RCREGをリードするとクリア) MOVLW '?' ; 「?」の文字コードをWregにロードする MOVWF INDF ; バッファに格納(「?」の文字を格納) BTFSS RCSTA,OERR ; オーバーランエラーのチェック(1:エラー,0:正常) GOTO CHKBF ; 正常であれば CHKBF のラベルへジャンプする ; OVER ; <オーバーランエラー時の処理> BCF RCSTA,CREN ; OERRのリセット(ビットCREN のクリアによりクリアする) BSF RCSTA,CREN ; 連続受信を許可する MOVLW '?' ; 「?」の文字コードをWregにロードする MOVWF INDF ; バッファに格納(「?」の文字を格納) GOTO CHKBF ; CHKBF のラベルへジャンプする SEND ; ****** データの送信ルーチン ****** MOVLW 0A0H ; バッファの先頭アドレスをセットする MOVWF FSR ; 間接アドレスポインタをリセットする LPSD MOVF INDF,W ; バッファに格納されているデータをWregにロードする CALL TX ; 送信サブルーチンへ MOVF INDF,W ; バッファに格納されているデータをWregに再ロードする SUBLW 0DH ; データから「CR」コードを引く BTFSC STATUS,Z ; 演算結果がゼロかチェック(データは終了コード「CR」?) GOTO TEXT ; データが「CR」のとき TEXTのラベルへジャンプする ; ****** バッファにデータが残っているかチェック ****** INCF FSR,F ; ポインタ +1 BTFSS STATUS,Z ; STATUSレジスタのZフラグビットが1だったら次をスキップ GOTO LPSD ; バッファに残っている LPSDのラベルへ戻り送信を続ける GOTO TEXT ; バッファが空である  TEXT のラベルへジャンプする TEXT ; ****** テキストデータの送信ルーチン ****** CLRF POINT ; テーブルポインタのリセット LPTEX ; MOVF POINT,W ; テーブルポインタの値をWregへロードする(OFFSET) CALL TABLE ; テキストデータの読み込みサブルーチンへ ADDLW 0 ; Wregレジスタに0を加算する BTFSC STATUS,Z ; 演算結果がゼロかチェック(テキストデータは「0」?) GOTO MAIN ; テキストデータが終了を示す「0」のとき MAINへジャンプ CALL TX ; テキストデータを出力するため送信サブルーチンへ INCF POINT,F ; テーブルポインタ +1 GOTO LPTEX ; LPTEX のラベルへ戻り繰り返す TABLE ; ****** テキストデータテーブル ****** ADDWF PCL,F ; PC+OFFSET DT "終了",0,0,0,0,0,0,0,0 ; TABLEの定義(PC+OFFSET相当のデータを持って戻る) ;*********************************************************** ; 送信サブルーチン ; 送信可能かのチェックは送信レジスタが空であることで確認 ; (つまり、TRMT=1で可能と判定する) ; (注)TXATAのあるバンクに注意 ;*********************************************************** TX MOVWF TEMP ; 送信するデータを変数(TEMP)に格納 BSF STATUS,RP0 ; Bank 1 へ切替 LPTX ; BTFSS TXSTA,TRMT ; 送信可能であるかチェック(1:可能, 0:禁止) GOTO LPTX ; 禁止であれば LPTX のラベル間を繰り返す ; BCF STATUS,RP0 ; Bank 0 へ戻す MOVF TEMP,W ; 変数(TEMP)に格納していた送信データをWregにロード MOVWF TXREG ; 送信データはTXREGレジスタを通してシリアル出力される RETURN ; メインルーチンへ戻る END